use crate::{
    animate::{Animator, LoopStrategy},
    class::ChildCommand,
    loader::GameSource,
    widget::{button_children, grid, node_text, node_text_a, GridInfo},
};
use bevy::prelude::*;
use std::time::Duration;

#[derive(Component, Clone, Copy)]
pub struct CollapseRelate(Entity);

pub fn collapse_grid(
    row: usize,
    col: usize,
    item_height: f32,
    title: impl Into<String>,
    gc: &mut ChildBuilder,
    children: impl FnMut(&mut ChildBuilder, usize, usize),
) {
    let id = button_children(collapse_title, gc, (), |gc| {
        node_text_a("\u{e7f9}", (collapse_title_arrow, collapse_title_arrow_ani), gc, ());
        node_text(title, collapse_title_text_style, gc, ());
    });
    let id1 = grid(row, col, item_height, collapse_grid_container, (), gc, Animator::default(), children);
    gc.entity_insert(id, CollapseRelate(id1));
}

fn collapse_title(mut style: Mut<Style>, mut background: Mut<BackgroundColor>) {
    style.width = Val::Percent(100.);
    style.height = Val::Px(30.);
    style.display = Display::Flex;
    style.flex_direction = FlexDirection::Row;
    style.align_items = AlignItems::Center;
    background.0 = Color::rgb_u8(115, 127, 157);
}

fn collapse_title_arrow(
    mut text: Mut<Text>,
    gm_res: Res<GameSource>,
    mut text_node_style: Mut<Style>,
) {
    text.sections[0].style.font = gm_res.font_icon.clone();
    text.sections[0].style.font_size = 12.0;
    text.sections[0].style.color = Color::WHITE;
    text_node_style.margin = UiRect::horizontal(Val::Px(5.));
}

fn collapse_title_arrow_ani(mut animator: Mut<Animator>) {
    animator
        .set_loop_strategy(LoopStrategy::Once)
        .set_pause(true)
        .add_change()
        .set_retain_change(true)
        .set_duration(Duration::from_millis(300))
        .set_text_value("\u{e7f9}".to_string())
        .set_text_color(Color::rgba(0., 0., 0., -0.5));
    animator
        .add_change()
        .set_retain_change(true)
        .set_duration(Duration::from_millis(300))
        .set_text_value("\u{e873}".to_string())
        .set_text_color(Color::rgba(0., 0., 0., 0.5));
}

fn collapse_title_text_style(
    mut style: Mut<Style>,
    mut text: Mut<Text>,
    gm_res: Res<GameSource>,
) {
    style.display = Display::Flex;
    style.align_items = AlignItems::Center;
    text.sections[0].style.font = gm_res.font_mono.clone();
    text.sections[0].style.font_size = 20.0;
    text.sections[0].style.color = Color::WHITE;
    text.justify = JustifyText::Center;
}

fn collapse_grid_container(
    mut style: Mut<Style>,
    mut background: Mut<BackgroundColor>,
    mut animator: Mut<Animator>,
    grid_info: Res<GridInfo>
) {
    style.width = Val::Percent(100.);
    style.height = Val::Px(0.);
    style.display = Display::Flex;
    background.0 = Color::WHITE;
    let h = grid_info.2 * grid_info.0 as f32;
    animator
        .set_loop_strategy(LoopStrategy::Once)
        .set_pause(true)
        .add_change()
        .set_retain_change(true)
        .set_duration(Duration::from_millis(300))
        .set_style_size(Val::Auto, Val::Px(-h));
    animator
        .add_change()
        .set_retain_change(true)
        .set_duration(Duration::from_millis(300))
        .set_style_size(Val::Auto, Val::Px(h));
}

pub fn collapse_grid_event(
    query_ani: Query<(&Interaction, &CollapseRelate, &Children), Changed<Interaction>>,
    mut query_animator: Query<&mut Animator>,
) {
    for (interaction, block, children) in query_ani.iter() {
        match *interaction {
            Interaction::Pressed => {
                if let Ok(mut animator) = query_animator.get_mut(block.0) {
                    let index = animator.get_exec_index();
                    if animator.get_pause() {
                        animator.set_pause(false).exec_index((index + 1) % 2);
                    }
                }
                for child in children.iter() {
                    if let Ok(mut animator) = query_animator.get_mut(*child) {
                        let index = animator.get_exec_index();
                        if animator.get_pause() {
                            animator.set_pause(false).exec_index((index + 1) % 2);
                        }
                    }
                }
            }
            _ => {}
        }
    }
}
